import express, { Request, Response, Router } from 'express';
import { PrismaClient } from '@prisma/client';
import { adminAuthMiddleware } from '../../middleware/adminAuth';
import { ApiResponse } from '../../utils/response';
import { priceService } from '../../services/priceService';
import { rewardCalculationService } from '../../services/rewardCalculationService';
import { getUserDailyRewardRate, autoUpgradeTier } from '../../utils/tierHelper';

const router: Router = express.Router();
const prisma = new PrismaClient();

// 获取充值申请列表
router.get('/list', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const {
      status,
      page = 1,
      limit = 20,
      startDate,
      endDate,
      userId,
      minAmount,
      maxAmount,
      exportAll = 'false' // 新增：导出全部数据参数
    } = req.query;

    // 获取当前登录用户信息
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminId = (req as any).adminId;
    const adminRole = (req as any).adminRole;
    const isPartner = (req as any).isPartner;

    // 构建查询条件
    const where: any = {};

    // 权限过滤：USER角色只能查看自己邀请的用户的充值记录
    if (userType === 'USER' && currentUserId) {
      // 查询该用户邀请的所有用户ID
      const referredUsers = await prisma.user.findMany({
        where: { referredBy: currentUserId },
        select: { id: true }
      });

      const referredUserIds = referredUsers.map(u => u.id);

      // 如果没有邀请任何用户，返回空列表
      if (referredUserIds.length === 0) {
        res.json(ApiResponse.success({
          records: [],
          summary: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          nearPrice: await priceService.getNearPrice(),
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total: 0,
            totalPages: 0
          }
        }));
        return;
      }

      // 限制只能查看邀请用户的充值记录
      where.userId = { in: referredUserIds };
    }

    // 权限过滤：合作伙伴只能查看自己邀请的用户的充值记录
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && isPartner && adminId) {
      const partnerUsers = await prisma.user.findMany({
        where: { partnerAdminId: adminId },
        select: { id: true }
      });

      const partnerUserIds = partnerUsers.map(u => u.id);

      // 如果没有用户，返回空列表
      if (partnerUserIds.length === 0) {
        res.json(ApiResponse.success({
          records: [],
          summary: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          nearPrice: await priceService.getNearPrice(),
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total: 0,
            totalPages: 0
          }
        }));
        return;
      }

      where.userId = { in: partnerUserIds };
    }

    if (status && status !== 'all') {
      where.status = status as string;
    }

    if (userId) {
      where.userId = parseInt(userId as string);
    }

    if (minAmount || maxAmount) {
      where.amount = {};
      if (minAmount) where.amount.gte = parseFloat(minAmount as string);
      if (maxAmount) where.amount.lte = parseFloat(maxAmount as string);
    }

    if (startDate || endDate) {
      where.createdAt = {};
      if (startDate) where.createdAt.gte = new Date(startDate as string);
      if (endDate) {
        const endDateTime = new Date(endDate as string);
        endDateTime.setHours(23, 59, 59, 999);
        where.createdAt.lte = endDateTime;
      }
    }

    // 判断是否导出全部
    const isExportAll = exportAll === 'true';

    // 获取充值记录
    const deposits = await prisma.depositRecord.findMany({
      where,
      include: {
        user: {
          select: {
            id: true,
            name: true,
            idNumber: true,
            mobileNumber: true,
            withdrawalBank: true,
            withdrawalAccount: true,
            accountHolder: true
          }
        }
      },
      orderBy: { createdAt: 'desc' },
      ...(isExportAll ? {} : {
        skip: (Number(page) - 1) * Number(limit),
        take: Number(limit)
      })
    });

    // 获取总记录数
    const total = await prisma.depositRecord.count({ where });

    // 获取当前NEAR价格
    const nearPrice = await priceService.getNearPrice();

    // 为每条充值记录计算对应的NEAR数量，并转换Decimal类型为数字
    const depositsWithNear = deposits.map(deposit => {
      const amount = Number(deposit.amount);
      const storedNearAmount = deposit.lockedNearAmount ? Number(deposit.lockedNearAmount) : 0;
      const storedNearPrice = deposit.lockedNearPrice ? Number(deposit.lockedNearPrice) : nearPrice;

      return {
        ...deposit,
        amount,
        lockedNearAmount: storedNearAmount,
        lockedNearPrice: storedNearPrice,
        nearAmount: storedNearAmount > 0 ? storedNearAmount : amount / nearPrice,
        nearPrice: storedNearPrice
      };
    });

    // 统计信息
    const summary = await prisma.depositRecord.groupBy({
      by: ['status'],
      where: status && status !== 'all' ? {} : where,
      _count: {
        status: true
      },
      _sum: {
        amount: true
      }
    });

    const statusSummary = {
      pending: { count: 0, amount: 0 },
      confirmed: { count: 0, amount: 0 },
      failed: { count: 0, amount: 0 },
      cancelled: { count: 0, amount: 0 }
    };

    summary.forEach(s => {
      const status = s.status.toLowerCase() as keyof typeof statusSummary;
      if (statusSummary[status]) {
        statusSummary[status].count = Number(s._count.status);
        statusSummary[status].amount = Number(s._sum.amount) || 0;
      }
    });

    res.json(ApiResponse.success({
      records: depositsWithNear,
      summary: statusSummary,
      nearPrice, // 返回当前NEAR价格
      pagination: {
        page: Number(page),
        limit: Number(limit),
        total: Number(total),
        totalPages: Math.ceil(Number(total) / Number(limit))
      }
    }));
  } catch (error) {
    console.error('충전 목록 조회 오류:', error);
    res.status(500).json(ApiResponse.error('충전 목록 조회에 실패했습니다.'));
  }
});

// 获取充值申请详情
router.get('/:id', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;

    const deposit = await prisma.depositRecord.findUnique({
      where: { id: parseInt(id) },
      include: {
        user: {
          select: {
            id: true,
            name: true,
            idNumber: true,
            mobileNumber: true,
            withdrawalBank: true,
            withdrawalAccount: true,
            accountHolder: true,
            mobileCarrier: true,
            entryCode: true,
            createdAt: true,
            referredBy: true
          }
        }
      }
    });

    if (!deposit) {
      res.status(404).json(ApiResponse.error('충전 기록이 존재하지 않습니다.'));
      return;
    }

    // 权限检查：USER角色只能查看自己邀请用户的充值记录
    if (userType === 'USER' && currentUserId) {
      if (deposit.user.referredBy !== currentUserId) {
        res.status(403).json(ApiResponse.error('이 충전 기록에 접근할 권한이 없습니다.'));
        return;
      }
    }

    // 获取用户余额信息
    const userBalance = await prisma.userBalance.findUnique({
      where: { userId: deposit.userId }
    });

    // 获取用户最近的充值历史
    const recentDeposits = await prisma.depositRecord.findMany({
      where: {
        userId: deposit.userId,
        id: { not: deposit.id }
      },
      select: {
        id: true,
        amount: true,
        status: true,
        createdAt: true,
        processedAt: true
      },
      orderBy: { createdAt: 'desc' },
      take: 5
    });

    res.json(ApiResponse.success({
      deposit,
      userBalance,
      recentDeposits
    }));
  } catch (error) {
    console.error('충전 상세 조회 오류:', error);
    res.status(500).json(ApiResponse.error('충전 상세 조회에 실패했습니다.'));
  }
});

// 处理充值申请（승인/거부）
router.post('/:id/process', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { action, note, actualNearAmount } = req.body; // action: 'confirm' | 'reject'
    const adminId = (req as any).adminId;
    const adminName = (req as any).adminName;
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;

    if (!['confirm', 'reject'].includes(action)) {
      res.status(400).json(ApiResponse.error('유효하지 않은 작업입니다. confirm 또는 reject만 가능합니다.'));
      return;
    }

    // 승인充值时必须提供 actualNearAmount
    if (action === 'confirm' && (!actualNearAmount || actualNearAmount <= 0)) {
      res.status(400).json(ApiResponse.error('실제 입금한 NEAR 수량을 입력해 주세요.'));
      return;
    }

    // 获取充值记录
    const deposit = await prisma.depositRecord.findUnique({
      where: { id: parseInt(id) },
      include: {
        user: {
          select: {
            name: true,
            idNumber: true,
            referredBy: true
          }
        }
      }
    });

    if (!deposit) {
      res.status(404).json(ApiResponse.error('충전 기록이 존재하지 않습니다.'));
      return;
    }

    // 权限检查：USER角色只能处理自己邀请用户的充值申请
    if (userType === 'USER' && currentUserId) {
      if (deposit.user.referredBy !== currentUserId) {
        res.status(403).json(ApiResponse.error('이 충전 기록을 처리할 권한이 없습니다.'));
        return;
      }
    }

    if (deposit.status !== 'PENDING') {
      res.status(400).json(ApiResponse.error('해당 충전 신청은 이미 처리되어 다시 처리할 수 없습니다.'));
      return;
    }

    if (action === 'confirm') {
      // 승인充值：更新用户余额和质押信息
      const result = await prisma.$transaction(async (tx) => {
        // 更新充值记录상태，保存实际NEAR数量
        const updatedDeposit = await tx.depositRecord.update({
          where: { id: parseInt(id) },
          data: {
            status: 'CONFIRMED',
            actualNearAmount: actualNearAmount, // 保存管理员实际存入的NEAR数量
            adminNote: note || `관리자 ${adminName}가 충전을 승인하고 ${actualNearAmount} NEAR을 입금했습니다.`,
            processedBy: adminId,
            processedAt: new Date()
          }
        });

        // 更新UserStaking质押本金
        // 注意：正常情况下用户注册时已创建 UserStaking 记录，这里只需要累加本金
        await tx.userStaking.update({
          where: { userId: deposit.userId },
          data: {
            stakedAmount: { increment: actualNearAmount } // 累加质押本金
          }
        });

        return updatedDeposit;
      });

      // 【自动等级升级】检查用户总投资金额，自动升级等级
      try {
        const userStaking = await prisma.userStaking.findUnique({
          where: { userId: deposit.userId }
        })

        if (userStaking) {
          const totalInvestment = Number(userStaking.stakedAmount) + Number(userStaking.lockedAmount)
          const upgradeResult = await autoUpgradeTier(deposit.userId, totalInvestment)

          if (upgradeResult.upgraded) {
            console.log(
              `🎉 用户 ${deposit.userId} 等级已自动升级: ${upgradeResult.oldTier} -> ${upgradeResult.newTier}, ` +
              `新日收益率: ${(upgradeResult.newDailyRate * 100).toFixed(2)}%`
            )
          }
        }
      } catch (error) {
        console.error(`❌ 用户 ${deposit.userId} 自动升级等级失败:`, error)
        // 不阻断充值流程，仅记录错误
      }

      // 【追加投资处理】充值成功后，检查是否需要重新计算当日收益
      try {
        await rewardCalculationService.recalculateDailyReward(deposit.userId);
        console.log(`✅ 用户 ${deposit.userId} 追加投资后已重新计算收益`);
      } catch (error) {
        console.error(`❌ 用户 ${deposit.userId} 重新计算收益失败:`, error);
        // 不阻断充值流程，仅记录错误
      }

      res.json(ApiResponse.success(result,
        `충전이 승인되었습니다: 고객이 ${Number(deposit.amount).toLocaleString('ko-KR')}원을 입금했고 실제 분배는 ${actualNearAmount} NEAR입니다.`
      ));
    } else {
      // 거부充值
      const updatedDeposit = await prisma.depositRecord.update({
        where: { id: parseInt(id) },
        data: {
          status: 'FAILED',
          adminNote: note || `관리자 ${adminName}가 충전을 거부했습니다.`,
          processedBy: adminId,
          processedAt: new Date()
        }
      });

      res.json(ApiResponse.success(updatedDeposit, `충전 신청이 거부되었습니다: ${note || '거절 사유가 제공되지 않았습니다.'}`));
    }
  } catch (error) {
    console.error('충전 신청 처리 오류:', error);
    res.status(500).json(ApiResponse.error('충전 신청 처리에 실패했습니다.'));
  }
});

// 批量处理充值申请
router.post('/batch-process', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { depositIds, action, note } = req.body;
    const adminId = (req as any).adminId;
    const adminName = (req as any).adminName;
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;

    if (!Array.isArray(depositIds) || depositIds.length === 0) {
      res.status(400).json(ApiResponse.error('처리할 충전 신청을 선택해 주세요.'));
      return;
    }

    if (!['confirm', 'reject'].includes(action)) {
      res.status(400).json(ApiResponse.error('유효하지 않은 작업입니다.'));
      return;
    }

    // 获取所有待处理的充值记录
    const deposits = await prisma.depositRecord.findMany({
      where: {
        id: { in: depositIds.map(id => parseInt(id)) },
        status: 'PENDING'
      },
      include: {
        user: {
          select: {
            name: true,
            referredBy: true
          }
        }
      }
    });

    if (deposits.length === 0) {
      res.status(400).json(ApiResponse.error('처리할 수 있는 충전 신청이 없습니다.'));
      return;
    }

    // 权限检查：USER角色只能批量处理自己邀请用户的充值申请
    if (userType === 'USER' && currentUserId) {
      const unauthorizedDeposits = deposits.filter(d => d.user.referredBy !== currentUserId);
      if (unauthorizedDeposits.length > 0) {
        res.status(403).json(ApiResponse.error('일부 충전 기록을 처리할 권한이 없습니다.'));
        return;
      }
    }

    let successCount = 0;
    let totalAmount = 0;

    if (action === 'confirm') {
      // 충전을 일괄 승인
      for (const deposit of deposits) {
        try {
          await prisma.$transaction(async (tx) => {
            // 更新充值记录상태
            await tx.depositRecord.update({
              where: { id: deposit.id },
              data: {
                status: 'CONFIRMED',
                adminNote: note || `관리자 ${adminName}가 충전을 일괄 승인했습니다.`,
                processedBy: adminId,
                processedAt: new Date()
              }
            });

            // 更新用户余额
            await tx.userBalance.upsert({
              where: { userId: deposit.userId },
              create: {
                userId: deposit.userId,
                balance: deposit.amount,
                frozen: 0,
                total: deposit.amount
              },
              update: {
                balance: { increment: deposit.amount },
                total: { increment: deposit.amount }
              }
            });
          });

          successCount++;
          totalAmount += Number(deposit.amount);
        } catch (error) {
          console.error(`충전 ${deposit.id} 처리에 실패했습니다:`, error);
        }
      }

      res.json(ApiResponse.success({
        successCount,
        totalCount: deposits.length,
        totalAmount
      }, `일괄 승인이 완료되었습니다. 처리 건수: ${successCount}건, 총액: ${totalAmount.toLocaleString('ko-KR')}원`));
    } else {
      // 충전을 일괄 거부
      const updateResult = await prisma.depositRecord.updateMany({
        where: {
          id: { in: deposits.map(d => d.id) }
        },
        data: {
          status: 'FAILED',
          adminNote: note || `관리자 ${adminName}가 충전을 일괄 거부했습니다.`,
          processedBy: adminId,
          processedAt: new Date()
        }
      });

      res.json(ApiResponse.success({
        successCount: updateResult.count,
        totalCount: deposits.length
      }, `일괄 거부가 완료되었습니다. 처리 건수: ${updateResult.count}건`));
    }
  } catch (error) {
    console.error('충전 신청 일괄 처리 오류:', error);
    res.status(500).json(ApiResponse.error('충전 신청 일괄 처리에 실패했습니다.'));
  }
});

// 获取充值统计数据
router.get('/stats/overview', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { period = 'today' } = req.query; // today, week, month, year

    // 获取当前登录用户信息
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminId = (req as any).adminId;
    const adminRole = (req as any).adminRole;
    const isPartner = (req as any).isPartner;

    let startDate: Date;
    const endDate = new Date();

    switch (period) {
      case 'week':
        startDate = new Date();
        startDate.setDate(startDate.getDate() - 7);
        break;
      case 'month':
        startDate = new Date();
        startDate.setMonth(startDate.getMonth() - 1);
        break;
      case 'year':
        startDate = new Date();
        startDate.setFullYear(startDate.getFullYear() - 1);
        break;
      default: // today
        startDate = new Date();
        startDate.setHours(0, 0, 0, 0);
        break;
    }

    // 构建查询条件
    const whereCondition: any = {
      createdAt: {
        gte: startDate,
        lte: endDate
      }
    };

    // 权限过滤：USER角色和PARTNER角色只能查看自己邀请用户的充值统计
    if (userType === 'USER' && currentUserId) {
      const referredUsers = await prisma.user.findMany({
        where: { referredBy: currentUserId },
        select: { id: true }
      });
      if (referredUsers.length === 0) {
        // 如果没有邀请任何用户，返回空统计
        res.json(ApiResponse.success({
          stats: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          pendingCount: 0,
          hourlyTrend: [],
          period
        }));
        return;
      }
      whereCondition.userId = { in: referredUsers.map(u => u.id) };
    } else if (userType === 'ADMIN' && adminRole === 'PARTNER' && isPartner && adminId) {
      const partnerUsers = await prisma.user.findMany({
        where: { partnerAdminId: adminId },
        select: { id: true }
      });
      if (partnerUsers.length === 0) {
        // 如果没有用户，返回空统计
        res.json(ApiResponse.success({
          stats: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          pendingCount: 0,
          hourlyTrend: [],
          period
        }));
        return;
      }
      whereCondition.userId = { in: partnerUsers.map(u => u.id) };
    }

    // 获取统计数据
    const stats = await prisma.depositRecord.groupBy({
      by: ['status'],
      where: whereCondition,
      _count: {
        status: true
      },
      _sum: {
        amount: true
      }
    });

    // 获取待处理的充值申请数量
    const pendingWhere: any = { status: 'PENDING' };
    if (whereCondition.userId) {
      pendingWhere.userId = whereCondition.userId;
    }
    const pendingCount = await prisma.depositRecord.count({
      where: pendingWhere
    });

    // 获取今日充值趋势（按小时）
    const hourlyStats = await prisma.$queryRaw`
      SELECT 
        HOUR(created_at) as hour,
        COUNT(*) as count,
        SUM(amount) as amount
      FROM deposit_records 
      WHERE DATE(created_at) = CURDATE()
        AND status = 'CONFIRMED'
      GROUP BY HOUR(created_at)
      ORDER BY hour
    ` as Array<{ hour: number; count: bigint; amount: string }>;

    const formattedStats = {
      pending: { count: 0, amount: 0 },
      confirmed: { count: 0, amount: 0 },
      failed: { count: 0, amount: 0 },
      cancelled: { count: 0, amount: 0 }
    };

    stats.forEach(s => {
      const status = s.status.toLowerCase() as keyof typeof formattedStats;
      if (formattedStats[status]) {
        formattedStats[status].count = s._count.status;
        formattedStats[status].amount = Number(s._sum.amount) || 0;
      }
    });

    res.json(ApiResponse.success({
      stats: formattedStats,
      pendingCount: Number(pendingCount),
      hourlyTrend: hourlyStats.map(h => ({
        hour: h.hour,
        count: Number(h.count),
        amount: parseFloat(h.amount) || 0
      })),
      period
    }));
  } catch (error) {
    console.error('충전 통계 조회 오류:', error);
    res.status(500).json(ApiResponse.error('충전 통계 조회에 실패했습니다.'));
  }
});

export default router;
